package cn.willbj.brief.java.lang.type.demo;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @see java.lang.reflect.Type
 * 
 * @see java.lang.reflect.ParameterizedType
 * @see java.lang.reflect.WildcardType
 * 
 * @see java.lang.reflect.GenericArrayType
 * 		数组类型
 *
 */
public class Demo01<T> {
	
	private Map<String, Integer> map;
	
	private T[] t;
	
	private List<? extends Number> l1;
	private List<? super Number> l2;  
	
	public static void main(String[] args) throws Exception {
		
		/* ParameterizedType */
		Demo01 demo01 = new Demo01();
		Field field = demo01.getClass().getDeclaredField("map");
		Type genericType = field.getGenericType();
		// 第一种打印方式
		if (genericType instanceof ParameterizedType) {
			Type[] arguments = ((ParameterizedType) genericType).getActualTypeArguments();
			System.out.println(Arrays.toString(arguments));
		}
		// 第二种打印方式 : 错误
		/*if (genericType instanceof ParameterizedType) {
			Type[] arguments = ((ParameterizedType) genericType).getActualTypeArguments();
			for (Type type : arguments) {
				if (type instanceof ParameterizedType) {
					System.out.println(type);
				}
			}
		}*/
		
		System.out.println("**************************");
		
		Field field2 = demo01.getClass().getDeclaredField("t");
		Type genericType2 = field2.getGenericType();
		if (genericType2 instanceof GenericArrayType) {
			Type genericComponentType = ((GenericArrayType) genericType2).getGenericComponentType();
			System.out.println(genericComponentType);
		}
		
		System.out.println("**************************");
		
		Field field3 = demo01.getClass().getDeclaredField("l1");
		Type genericType3 = field3.getGenericType();
		if (genericType3 instanceof ParameterizedType) {
			Type[] arguments = ((ParameterizedType) genericType3).getActualTypeArguments();
			System.out.println(Arrays.toString(arguments));
			for (Type type : arguments) {
				if (type instanceof WildcardType) {
					System.out.println(((WildcardType) type).getLowerBounds());
					System.out.println(((WildcardType) type).getUpperBounds());
				}
			}
			
		}
	}
	
}
